package com.sdw.message.util;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;

public class DateUtils {
	public final static int Hour = 1;
	public final static int Date = 2;
	public final static int Month = 3;

	public static boolean isMonthEndDate(Calendar date) {
		Calendar monthEndDay;
		try {
			monthEndDay = DateUtils.parseCalendar(
					String.format("%s01", DateUtils.format(date, "yyyyMM")),
					"yyyyMMdd");
			monthEndDay.add(Calendar.MONTH, 1);
			monthEndDay.add(Calendar.DATE, -1);
			if (monthEndDay.get(Calendar.DATE) == date.get(Calendar.DATE))
				return true;
			else
				return false;
		} catch (ParseException e) {
			throw new RuntimeException(e);
		}
	}

	public static boolean isWeekEndDate(Calendar date) {
		return date.get(Calendar.DAY_OF_WEEK) == 1;
	}

	/*
	 * date and datetime format especially for sql-sever
	 */
	public static String formatDateTime(Date date) {
		return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS", Locale.ENGLISH)
				.format(date);
	}

	public static String formatDate(Date date) {
		return new SimpleDateFormat("yyyy-MM-dd", Locale.ENGLISH).format(date);
	}

	public static String formatDate(Date date, String pattern) {
		return new SimpleDateFormat(pattern, Locale.ENGLISH).format(date);
	}

	public static Date parseDate(String strDate) throws ParseException {
		return new SimpleDateFormat("yyyy-MM-dd", Locale.ENGLISH)
				.parse(strDate);
	}

	public static Date parseDatetime(String strDate) throws ParseException {
		try {
			return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.ENGLISH)
					.parse(strDate);
		} catch (ParseException e) {
			return new SimpleDateFormat("yyyy-MM-dd", Locale.ENGLISH)
					.parse(strDate);
		}
	}

	/*
	 * free pattern
	 */
	public static String format(Date date, String pattern) {
		if (date == null)
			return "";
		DateFormat format = new SimpleDateFormat(pattern, Locale.ENGLISH);
		return format.format(date);
	}

	/*
	 * free pattern
	 */
	public static String format(Calendar calendar, String pattern) {
		DateFormat format = new SimpleDateFormat(pattern, Locale.ENGLISH);
		return format.format(calendar.getTime());
	}

	public static Date parse(String strDate, String pattern)
			throws ParseException {
		DateFormat format = new SimpleDateFormat(pattern, Locale.ENGLISH);
		return format.parse(strDate);
	}

	public static Calendar parseCalendar(String strDate, String pattern)
			throws ParseException {

		DateFormat format = new SimpleDateFormat(pattern, Locale.ENGLISH);
		Date date = format.parse(strDate);
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		return calendar;
	}

	public static long getAbsoluteDays(Date beforDate, Date afterDate) {
		return (beforDate.getTime() - afterDate.getTime())
				/ (1000 * 60 * 60 * 24); // dateOrHour
	}

	public static long getAbsoluteHours(Date beforDate, Date afterDate) {
		return (beforDate.getTime() - afterDate.getTime()) / (1000 * 60 * 60); // dateOrHour
	}

	public static int toDateInt(Date date) {
		return Integer.parseInt(format(date, "yyMMdd"));
	}

	public static int toDateInt(Calendar calendar) {
		return Integer.parseInt(format(calendar.getTime(), "yyMMdd"));
	}

	public static int toHourInt(Date date) {
		return Integer.parseInt(format(date, "yyMMddHH"));
	}

	public static int toHourInt(Calendar calendar) {
		return Integer.parseInt(format(calendar.getTime(), "yyMMddHH"));
	}

	/**
	 * 获取日期对象
	 * 
	 * @param dateOrHour
	 *            6位数据为：120301 8位小时数据：12030101
	 * @return
	 */
	public static Date toDate(int dateOrHour, int fieldType) {
		return toCalendar(dateOrHour, fieldType).getTime();
	}

	public static Date toDateBySecond(long second) {
		if (second < 999999999999L || second > 29999999999999L) {
			throw new RuntimeException("this second " + second
					+ " out of range from 999999999999L to 29999999999999L.");
		}
		try {
			return parse(Long.toString(second), "yyyyMMddHHmmss");
		} catch (ParseException e) {
			throw new RuntimeException("this second " + second
					+ " don't parse to date.", e);
		}
	}

	public static long toSecondValue(Date date) {
		return Long.parseLong(format(date, "yyyyMMddHHmmss"));
	}

	public static long toSecondValue(Calendar calendar) {
		return toSecondValue(calendar.getTime());
	}

	/**
	 * 获取日期日历对象
	 * 
	 * @param dateOrHour
	 *            6位数据为：120301 8位小时数据：12030101
	 * @return
	 */
	public static Calendar toCalendar(String dateOrHour, int fieldType) {
		if (dateOrHour.startsWith("20")) {
			dateOrHour = dateOrHour.substring(2);
		}
		return DateUtils.toCalendar(Integer.parseInt(dateOrHour), fieldType);
	}

	public static Date toDate(String dateOrHour, int fieldType) {
		if (dateOrHour.startsWith("20") && fieldType == Date) {
			dateOrHour = dateOrHour.substring(2);
		}
		return DateUtils.toCalendar(Integer.parseInt(dateOrHour), fieldType)
				.getTime();
	}

	/**
	 * 获取日期日历对象 抱歉201208即时一个日期又是一个月份，设计失误，所以必须传字段FieldType，此值有常量Hour，Date,Month
	 * 
	 * @param dateOrHour
	 *            6位数据为：120301 8位小时数据：12030101
	 * @return
	 */
	public static Calendar toCalendar(int dateOrHour, int fieldType) {
		if (fieldType == Date) {
			if (dateOrHour < 100000 || dateOrHour > 990000) {
				throw new RuntimeException(
						String.format(
								"date value must be between 100000 and 990000,this value is %d ",
								dateOrHour));
			}

			Calendar date = Calendar.getInstance();
			date.set(2000 + (dateOrHour / 10000),
					((dateOrHour % 10000) / 100) - 1, dateOrHour % 100, 0, 0, 0);
			date.set(Calendar.MILLISECOND, 0);
			return date;
		} else if (fieldType == Hour) {
			if (dateOrHour < 10000000 || dateOrHour > 99000000) {
				throw new RuntimeException(
						String.format(
								"hour value must be between 10000000 and 99000000,this value is %d ",
								dateOrHour));
			}

			Calendar date = Calendar.getInstance();
			date.set(2000 + (dateOrHour / 1000000),
					((dateOrHour % 1000000) / 10000) - 1,
					(dateOrHour % 10000) / 100, dateOrHour % 100, 0, 0);
			date.set(Calendar.MILLISECOND, 0);
			return date;
		} else if (fieldType == Month) {
			if (dateOrHour < 201000 || dateOrHour > 209900) {
				throw new RuntimeException(
						String.format(
								"month value must be between 201000 and 209900,this value is %d ",
								dateOrHour));
			}

			Calendar date = Calendar.getInstance();
			date.set(dateOrHour / 100, dateOrHour % 100 - 1, 1, 23, 0, 0);
			date.set(Calendar.MILLISECOND, 0);
			date.add(Calendar.MONTH, 1);
			date.add(Calendar.DATE, -1);
			return date;
		} else {
			throw new IllegalArgumentException(String.format(
					"dateOrHour[%d] invalid,eg 120101 and 12010101,",
					dateOrHour));
		}
	}

	public static boolean equalsDay(Date date, Date otherDate) {
		return format(date, "yyyyMMdd").equalsIgnoreCase(
				format(otherDate, "yyyyMMdd"));
	}

	public static String getYesterdayDateString(String date) {
		Date today;
		Calendar cal = Calendar.getInstance();
		try {
			today = parseDate(date);
		} catch (ParseException e) {
			today = new Date();
		}

		cal.setTime(today);
		cal.set(Calendar.DATE, cal.get(Calendar.DATE) - 1);
		return formatDate(cal.getTime());
	}

	public static String getYesterdayDateString(Date date, String pattern) {
		Date yesterday = getYesterdayDateString(date);
		return format(yesterday, pattern);
	}

	public static Date getYesterdayDateString(Date date) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		cal.set(Calendar.DATE, cal.get(Calendar.DATE) - 1);
		return cal.getTime();
	}

	public static Date getFirstdayOfCurrentMonth() {
		Calendar cal = Calendar.getInstance();
		cal.set(Calendar.DAY_OF_MONTH, 1);
		Date beginTime = cal.getTime();
		return beginTime;
	}

}
